package com.zhb.services;

/**
 * Created by jarvan4dev on 16/5/22.
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.zhb.entity.BookInfo;
import com.zhb.entity.Records;
import com.zhb.exception.BookNotFoundException;
import com.zhb.util.HtmlUtils;
import com.zhb.util.HttpUtils;
import com.zhb.util.XMLUtilities;
import org.apache.http.client.HttpClient;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 图书检索等
 */
public class BookService {

    private final HttpClient httpClient;

    private final String holdingPreviewUri = "http://27.191.198.3:7088/opac/book/holdingpreview/%s?curLibcodes=";

    private final String simpleDeatilUri = "http://27.191.198.3:7088/opac/book/%s?view=simple";

    private final String bookOtherInfoUri = "http://api.interlib.com.cn:6699/interes/api/book/isbn/%s/?glc=P2HBJ0315013&returnType=json&callback=insertAllBookMetaInfo&jsoncallback=jQuery16204640514467365714_1464106839002&_=1464107119748";

    private final String bookCoverInfoUri = "http://api.interlib.com.cn/interlibopac/websearch/metares?cmdACT=getImages&isbns=";

    private final String pageUrl = "http://27.191.198.3:7088/opac/search?q=q&searchType=standard&isFacet=true&view=standard&searchWay=title&rows=10&sortWay=score&sortOrder=desc&searchWay0=marc&q0=&logical0=AND&page=";

    public BookService(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

    private static final String searchUri = "http://27.191.198.3:7088/opac/search?q=%s&searchWay=title&scWay=dim&searchSource=reader";

    public List<BookInfo> search(String bookName) throws IOException, BookNotFoundException {
        String encodedBookName = URLEncoder.encode(bookName, "UTF-8");
        String html = HttpUtils.doGet(httpClient, String.format(searchUri, encodedBookName));
        return dealSearchResult(html);
    }

    private List<BookInfo> dealSearchResult(String html) throws BookNotFoundException, IOException {
        Document document = Jsoup.parse(html);
        List<BookInfo> bookInfoList = resolve(document);
        Element pageEle = document.getElementsByClass("meneame").first();
        bookInfoList.addAll(deepSearch(pageEle));
        return bookInfoList;
    }

    private List<BookInfo> deepSearch(Element pageEle) throws IOException, BookNotFoundException {
        String pageText = pageEle.child(0).text();
        String pageCount = pageText.split(" ")[1];
        int pages = Integer.parseInt(pageCount);
        List<BookInfo> bookInfoList = Lists.newArrayList();
        if (pages > 1) {
            for (int i=2; i <= pages; i++){
                String nextPage = HttpUtils.doGet(httpClient, pageUrl+i);
                Document document = Jsoup.parse(nextPage);
                bookInfoList.addAll(resolve(document));
            }
        }
        return bookInfoList;
    }

    // 公共的解析函数
    private List<BookInfo> resolve(Document document) throws BookNotFoundException, IOException {
        Element resultList = document.getElementsByClass("resultList").first();
        if (resultList == null) {
            throw new BookNotFoundException();
        }
        Element resultTable = resultList.getElementsByClass("resultTable").first();
        Elements trs = resultTable.getElementsByTag("tr");
        List<BookInfo> bookInfoList = Lists.newArrayList();
        for (Element tr : trs) {
            BookInfo bookInfo = new BookInfo();
            // 此处的isbn不是bookInfo中的isbn,请注意
            String isbn = tr.getElementsByClass("coverTD").first().getElementsByTag("img").first().attr("isbn").replace("-", "");
            // 获取封面
            String url = bookCoverInfoUri + isbn;
            String jsonStr = HttpUtils.doGet(httpClient, url);
            if (!Strings.isNullOrEmpty(jsonStr)){
                jsonStr = jsonStr.substring(1, jsonStr.length()-1);
                JSONObject json = JSON.parseObject(jsonStr);
                JSONArray jsonArray = json.getJSONArray("result");
                if (jsonArray.size()>0) {
                    String coverLink = jsonArray.getJSONObject(0).getString("coverlink");
                    bookInfo.setCoverLink(coverLink);
                }
            }
            //String coverImg = tr.getElementsByClass("coverTD").first().getElementsByTag("img").first().attr("src");
            //bookInfo.setCoverLink(coverImg);
            Element bookBriefInfo = tr.getElementsByClass("bookmeta").first();
            dealBriefInfo(bookBriefInfo, bookInfo);
            getHoldPreviewInfo(bookInfo);
            getBookSimpleDetail(bookInfo);
            getBookOtherInfo(bookInfo);
            bookInfoList.add(bookInfo);
        }
        return bookInfoList;
    }

    private void dealBriefInfo(Element bookBriefInfo, BookInfo bookInfo) {
        String bookrecno = bookBriefInfo.attr("bookrecno");
        bookInfo.setId(bookrecno);

        String bookName = bookBriefInfo.getElementsByClass("bookmetaTitle").text();
        bookInfo.setBookName(bookName);
        String author = bookBriefInfo.child(1).text().split(":")[1].replace("著", "");
        bookInfo.setAuthor(author);
        String publishInfo = bookBriefInfo.child(2).text().replace(":", " ");
        bookInfo.setPublisher(publishInfo.split(" ")[1]);
        bookInfo.setPublishDate(publishInfo.split(" ")[3]);
    }

    // 根据bookId从网络请求中获取书的更多信息
    private void getHoldPreviewInfo(BookInfo bookInfo) throws IOException {
        String holdInfoXml = HttpUtils.doGet(httpClient, String.format(holdingPreviewUri, bookInfo.getId()));
        //System.out.println(holdInfoXml);
        Records records = XMLUtilities.unMarshall(holdInfoXml, Records.class);
        if (records != null && records.getRecords() != null) {
            bookInfo.setCopyCount(records.getRecords().size());
            bookInfo.setBiblio(records.getRecords().get(0).getCallno());
        }
    }

    private void getBookSimpleDetail(BookInfo bookInfo) throws IOException {
        String simpleDetail = HttpUtils.doGet(httpClient, String.format(simpleDeatilUri, bookInfo.getId()));
        //System.out.println(simpleDetail);
        Document document = Jsoup.parse(HtmlUtils.formatHtml(simpleDetail));
        Element bookInfoTable = document.getElementById("bookInfoTable");
        /**
         * 解析这个table即可, 可以参看 #LoanService
         * <code> LoanService @</code>
         * @See LoanService#get
         */
        // 先解析其isbn
        String content = bookInfoTable.getElementsByClass("rightTD").first().text();
        String isbn = content.split(" ")[0];
        bookInfo.setISBN(isbn);
    }

    private void getBookOtherInfo(BookInfo bookInfo) throws IOException {
        String isbn = bookInfo.getISBN();
        if (!Strings.isNullOrEmpty(isbn)) {
            String jsonStr = HttpUtils.doGet(httpClient, String.format(bookOtherInfoUri, isbn));
            JSONObject bookJSON = JSON.parseObject(jsonStr.substring(22, jsonStr.length()-1));
            JSONObject result = bookJSON.getJSONObject("result");
            if (result!=null){
                bookInfo.setTable(result.getString("catalog"));
                bookInfo.setBriefIntro(result.getString("summary"));
                bookInfo.setMark(result.getString("previewContent"));
            }
        }
    }

    // 跳转到某一页
    private String toOnePage(String pageNum) throws IOException {
        return HttpUtils.doGet(httpClient, pageUrl+pageNum);
    }
}
